import { HttpLib } from '@framework/useProjectHttp/httplib.class'
import { HTTP_ERROR_MESSAGE } from '@framework/useProjectHttp/http_error_message'
import type { AxiosResponse } from 'axios'
import { AxiosError } from 'axios'

type MsgKey = keyof typeof HTTP_ERROR_MESSAGE

// 全局保存
let _httpLib: HttpLib
// 错误提示函数
let _tipError: (msg: string) => void

/**
 * 从返回数据中，获取错误消息
 * @param response
 */
function getMsgFromResponse(response: AxiosResponse) {
  if (response.status !== 200) {
    const msg = HTTP_ERROR_MESSAGE[`response.status=${response.status}` as MsgKey]
    return (msg || `数据响应状态异常[response.status=${response.status}]`)
  }
  if (response.data.code !== 200) {
    const msg = HTTP_ERROR_MESSAGE[`response.data.code=${response.data.code}` as MsgKey]
    return (msg || response.data.message || `数据接口报错[response.data.code=${response.data.code}]`)
  }
}

/**
 * 从错误数据中，获取错误消息
 * @param error
 */
function getMsgFromError(error: AxiosError) {
  if (error instanceof AxiosError) {
    // 若存在返回体，则从返回体中获取错误消息
    if (error.response)
      return getMsgFromResponse(error.response)

    if (error.code === 'ERR_CANCELED')
      return false // 手动取消接口,不需要错误提醒
    // 错误消息
    const msg = HTTP_ERROR_MESSAGE[`error.code=${error.code}` as MsgKey] || `请求错误，请稍后重试[${error.code}]`
    return msg
  }
}

/**
 * http库 通用版本
 * @param {boolean} skipError 是否跳过错误提示
 * @returns
 */
export default function (options?: { skipError?: boolean }) {
  if (_httpLib)
    return _httpLib

  _httpLib = new HttpLib({
    hookError(error) {
      if (!getMsgFromError(error))
        return // 手动中断接口,不需要错误提醒
      let msg = ''
      if (error instanceof AxiosError)
        msg = getMsgFromError(error)

      else
        msg = `未捕获异常[${error.message}]`

      // 判断是否跳过错误提示
      if (!options?.skipError)
        _tipError(msg)
    },

    hookRequest(config) {
      return config
    },

    hookResponse(response) {
      // 获取错误提示
      const errMsg = getMsgFromResponse(response)
      if (errMsg)
        _tipError(errMsg)

      if (response.status === 200 && response.data.code === 200)
        return response.data.data

      return Promise.reject(response)
    },
  })
  return _httpLib
}

/**
 * http函数库的初始化
 * @param options
 * @param options.tipError 报错的回调函数，错误信息将通过此函数回调
 */
export function initHttp(options: { tipError: (msg: string) => void }) {
  _tipError = options.tipError
}

/**
 * 判断是否是 AxiosResponse类型
 * 包含status、statusText即认为是AxiosResponse类型
 * @param obj
 * @returns
 */
// function isAxiosResponse(obj: any): obj is AxiosResponse {
//   const temp = (obj as AxiosResponse)
//   return typeof temp.status !== 'undefined'
//     && typeof temp.statusText !== 'undefined'
// }
